// 什么是DOM
// 1.DOM---> Document Object Model
// 2.DOM定义了表示和修改文档所需的方法。DOM对象即为宿主对象，由浏览器厂商定义，
//    用来操作html和xml功能的一类对象的集合。也有人成DOM是对html以及xml的标准编程接口。


// 弹窗
alert('警告框')
confirm('询问框')  //返回结果(true， false)
prompt('输入框')   //返回结果(输入什么内容就返回什么内容)


// 1.通过标签名来选择元素
var div = document.getElementsByTagName('div')  //选中所有div
var div = document.getElementsByTagName('div')[0]  //选中第一个div
var div = document.getElementsByTagName('*');  //如果在里面写*号表示选中所有元素




// 在js中创建一个div
var div = document.createElement('div');

// 把创建的div插入到body中
document.body.appendChild(div)


// 定时器
setInterval(function () {

}, 100)


// 清除定时器
var time = setInterval(function () {
    clearInterval(time)  //清除定时器的方法
}, 100)



// 打印键盘事件对象
document.onkeydown = function (e) {
    var event = e || windows.event;
    console.log(event)
    console.log(event.key)   //打印按得是什么键
}


// 鼠标滑过事件
ul.onmouseover = function (e) {
    var event = e || window.event;    //兼容性问题
    var target = event.target || event.srcElement;   //事件源对象(兼容性问题)
    console.log(target,event)
}



// 获取属性值和设置属性名和值 getAttribute setAttribute
var input = document.getElementsByTagName('input')[0];
document.onclick = function () {
    input.getAttribute('type');       //获取input的中type属性的值
    input.setAttribute('type', 'button')   //给input中的type属性附上button值
}





// 1.对节点的增删改查
// 查
// 查看元素节点
// document代表整个文档
document.getElementById(); //元素id在ie8以下的浏览器，不区分id大小写，而且匹配name属性的元素
document.getElementsByTagName();  //标签名
document.getElementsByName();  //需要注意，只有部分标签name可生效(表单，表单元素,img iframe)
document.getElementsByClassName(); //类名-->ie8和ie8以下的ie版本中没有，可以多个class一起


// querySelector 和 querySelectorAll不是实时的，相当于照相，实时的就相当于直播，这两个选出来是副本
document.querySelector() //css选择器，在ie7和ie7以下的版本中没有   
// 写法
var div = document.querySelector('#div > .p > a')  //css中可以怎么选择标签queryselectory就可以怎么选择标签
document.querySelectorAll() //css选择器，在ie7和ie7以下的版本没有





// 遍历节点树
parentNode  //父节点(最顶端的parentNode为#document)
childNodes  //子节点们(选出来是一组)
firstChild  //第一个子节点
lastChild   //最后一个节点
nextSibling  //后一个兄弟节点
previousSibling //前一个兄弟节点


// 遍历元素节点数
parentElement  //返回当前元素的子元素节点(IE不兼容)
children       //子元素节点
childElementCount  //返回子元素节点的个数 相当于node.children.length
firstElementChild  //第一个子元素节点(IE不兼容)
lastElementChild   //最后一个字元素节点(IE不兼容)
nextElementSibling //返回后一个兄弟元素节点(IE不兼容)
previousElementSibling //返回前一个兄弟元素节点(IE不兼容)


// 节点的类型
// 元素节点 --- 1
// 属性节点 --- 2
// 文本节点 --- 3
// 注释节点 --- 8
// document --- 9
// DocumentFragment = 11

// 节点的四个属性
nodeName  //元素的标签名，一大些形式表示，只读
nodeValue //Text节点或comment节点的文本内容，可读写
nodeType  //该节点的类型，只读
attributes //Element节点的属性，返回一个类数组，包含元素中的所有属性
hasChildNodes()  //节点的一个方法，有孩子节点吗，返回true或false



// DOM结构树(结构如下document继承自HTMLDocument.prototype, 以此类推)
// document ---> HTMLDocument.prototype ---> Document.prototype

// HTMLElement下面有这些东西
    // HTMLHeadElement
    // HTMLBodyElement
    // HTMLTitleElement
    // HTMLParagraphElement
    // HTMLInputElement
    // HTMLTableElement

document.documentElement  //它指的就是html






// 练习
// 1.遍历元素节点树(在原型上编程)
var div = document.getElementsByTagName('div')[0];
var classArr = {
    length : 0,
    push : Array.prototype.push,
    splice : Array.prototype.splice,
}
HTMLElement.prototype.allElement = function () {
    var len = this.children.length;
    for(var i = 0; i < len; i ++) {
        classArr.push(this.children[i])
        if(this.children[i].hasChildNodes()){
            this.children[i].allElement();
        }
    }
    return classArr;
}
console.log(div.allElement())



// 2.封装函数，返回元素e的第n层祖先元素节点
var em = document.getElementsByClassName('zhangsan')[0];
function returnParentElement(n, elem) {
    for(var i = 0; i < n ; i ++) {
        if(elem == null) {
            return
        }
        elem = elem.parentElement;
    }
    return elem;
}
console.log(returnParentElement(5, em));




// 封装mychildren
Element.prototype.mychildren = function () {
    var child = this.childNodes;
    var len = child.length;
    var arr = []
    for(var i = 0; i < len; i ++) {
        if(child[i].nodeType == 1) {
            arr.push(child[i])
        }
    }
    return arr;
}
var div = document.getElementsByTagName('div')[0];
div.mychildren();



// 封装hasChildren()方法，不可用children属性
Element.prototype.myhasChildNodes = function () {
    var len = this.childNodes.length;
    for(var i = 0; i < len; i ++) {
        if(this.childNodes[i].nodeType ==1) {
            return true;
        }
    }
    return false;
}
var div = document.getElementsByTagName('div')[0];
div.myhasChildNodes();





// 封装函数，返回元素e的第n个兄弟元素节点，n为正，返回后面的兄弟元素节点，
// n为负，返回前面的，n为0，返回自己。
// nextElementSibling //返回前一个兄弟元素节点(IE不兼容)
// previousElementSibling //返回后一个兄弟元素节点(IE不兼容)
var strong = document.getElementsByTagName('strong')[0];
function returnToSiblingNode(e, n) {
    var count = 0;
    if(n > 0) {
        for(var i = 0; i < n; i ++) {
            if(e == null) {
                return null;
            }
            e = e.previousElementSibling
        }
        return e;
    }else if(n < 0) {
        for(var i = n; i < 0; i ++) {
            if(e == null) {
                return null;
            }
            e = e.nextElementSibling;
            count += 1;
        }
        return e;
    }else {
        return e;
    }
}



// 封装函数，返回元素e的第n个兄弟元素节点，n为正，返回后面的兄弟元素节点，
// n为负，返回前面的，n为0，返回自己。
// nextElementSibling //返回前一个兄弟元素节点(IE不兼容)
// previousElementSibling //返回后一个兄弟元素节点(IE不兼容)
// 成哥写的
var strong = document.getElementsByTagName('strong')[0];
function retSibling(e, n) {
    while(e && n) {
        if(n > 0) {
            e = e.nextElementSibling;
            n --
        }else {
            e = e.previousElementSibling;
            n++
        }
    }
    return e;
}






// 封装函数，返回元素e的第n个兄弟元素节点，n为正，返回后面的兄弟元素节点，
// n为负，返回前面的，n为0，返回自己。
// nextElementSibling //返回前一个兄弟元素节点(IE不兼容)
// previousElementSibling //返回后一个兄弟元素节点(IE不兼容)
// 成哥写的(没有兼容性问题的)
var strong = document.getElementsByTagName('strong')[0];
function restSibling(e, n) {
    while(e && n) {
        if(n > 0) {
            if(e.nextElementSibling){
                e = e.nextElementSibling
            }else{
                for(e = e.nextSibling;e &&  e.nodeType != 1; e = e.nextSibling) {};
            }
            n --
        }else {
            if(e.previausElementSibling){
                e = e.previausElementSibling
            }else{
                for(e = e.previousSibling;e && e.nodeType != 1; e = e.previousSibling) {};
            }
            n ++;
        }
    }
    return e;
}





// 元素的增、插、删、替换
// 增
var div = document.createElement('元素名称');  //创建元素
var comm = document.createComment('创建一个注释节点');   //创建注释节点
var text = document.createTextNode('创建一个文本节点');  //创建文本节点
document.createDocumentFragment();  //创建文档碎片节点


// 插
div.appendChild();  //相当于数组的push，如果把页面里面已有的东西appendChild就是剪切
div.insertBefore();  //父亲调用，把谁插入到谁前面
// 例如：
var strong = document.createElement('strong');
var div = document.getElementsByTagName('div')[0];
var span = div.getElementsByTagName('span')[0];
div.insertBefore(strong, span);   //在div下面，把创建出来的strong插入到span前面

// 删
div.removeChild(li);  //父节点调用removeChild方法删除子节点li或者是其他的(剪切操作)
div.remove();       //自己调用一个方法删除自己

// 替换
div.replaceChild(new, origin);  //父级调用，用什么替换什么，前面的参数写新的，后面的参数写老的






// Element节点的一些属性
div.innerHTML   //获取div里面的所有内容
div.innerHTML = '内容'    //可以改变标签里面的内容(覆盖操作)
div.innerHTML += '123';   //在后面追加内容
div.innerText(火狐不兼容) /textContent(老版本IE不好使)
div.innerText //获取标签里面的文本内容
div.innerText = '123';  //给标签赋值(覆盖操作)

// Element节点的一些方法
setAttribute()
div.setAttribute('id','test');  //给元素添加属性名和属性值
getAttribute();       
div.getAttribute('id')    //获取元素的属性值








// 封装函数insertAfter(); 功能类似于insertBefore();
// insertAFter(), 在什么元素之后插入什么元素
// 提示：可忽略老版本浏览器，直接在Element.prototype上编程
Element.prototype.insertAfter = function(insertElement, siblingNode) {
    var beforeNode = siblingNode.nextElementSibling;
    if(beforeNode == null) {
        this.appendChild(insertElement);
    }else{
        this.insertBefore(insertElement, beforeNode);
    }
}



// 将目标节点内部的节点顺序逆序
// eg:<div><a></a><em></em></div>
var div = document.getElementsByTagName('div')[0];
Element.prototype.rev = function() {
    var len = this.children.length - 1;
    for(var i = len-1; i >= 0; i --) {
        this.appendChild(this.children[i])
    }
}
div.rev();



// 日期对象Date()
var date = new Date();
// 获取时间
date.getFullYear();     //从 Date 对象以四位数字返回年份。
date.getDate();         //从 Date 对象返回一个月中的某一天 (1 ~ 31)。
date.getMonth();        //从 Date 对象返回月份 (0 ~ 11)。
date.getDay();          //从 Date 对象返回一周中的某一天 (0 ~ 6) 0是周日
date.getHours();        //返回 Date 对象的小时 (0 ~ 23)。 
date.getMinutes();      //返回 Date 对象的分钟 (0 ~ 59)。
date.getSeconds();      //返回Date对象的的秒数 (0 ~ 59)。
date.getMilliseconds(); //返回 Date 对象的毫秒(0 ~ 999)。
date.getTime();         //返回 1970 年 1 月 1 日至今的毫秒数。  最常用的


// 设置时间
date.setDate()	//设置 Date 对象中月的某一天 (1 ~ 31)。
date.setMonth()	//设置 Date 对象中月份 (0 ~ 11)。
date.setFullYear()	//设置 Date 对象中的年份（四位数字）。
date.setHours()	//设置 Date 对象中的小时 (0 ~ 23)。
date.setMinutes()	//设置 Date 对象中的分钟 (0 ~ 59)。
date.setSeconds()	//设置 Date 对象中的秒钟 (0 ~ 59)。
date.setMilliseconds()	//设置 Date 对象中的毫秒 (0 ~ 999)。
date.setTime()	//以毫秒设置 Date 对象。
date.toString();  //设置成字符串



// 计算程序运行的时间(记录程序运行前后的时间，然后用运行后的时间减去运行前的时间)
var firstTime = new Date().getTime();
for(var i = 0; i < 100000000; i ++) {}
var first1Time = new Date().getTime();
console.log(first1Time - firstTime);



// 设置一个时间等到了这个时间的时候就执行什么东西
var date = new Date();
date.setMinutes(42);
var test = setInterval(function () {
    if(new Date().getTime() - date.getTime() > 1000){
        console.log('test');
        clearInterval(test);
    }
}, 1000)






// 封装函数，打印当前是何年何月何时，几分几秒
var div = document.getElementsByTagName('div')[0];
function timeFn() {
    var date = new Date();
    var year = date.getFullYear();
    var month = date.getMonth()+1;
    var day = date.getDate();
    var hours = date.getHours();
    var minutes = date.getMinutes();
    var seconds = date.getSeconds();
    var Day = date.getDay();
    if(minutes < 10) {
        minutes = "0" + minutes; 
    }
    if(seconds < 10){
        seconds = "0" + seconds
    }
    
    switch(Day) {
        case 0:
            Day = "星期日"
            break;
        case 1:
            Day = "星期一"
            break;
        case 2:
            Day = "星期二"
            break;
        case 3:
            Day = "星期三"
            break;
        case 4:
            Day = "星期四"
            break;
        case 5:
            Day = "星期五"
            break;
        case 6:
            Day = "星期六"
            break;

    }
    var time = year + '年 ' + month + '月 ' +  day + "日 " + hours + "点 " + minutes + "分 " + seconds + '秒 ' + Day;
    div.innerHTML = time;
}
setInterval(function () {
    timeFn();
},1000)





// js定时器
// 全局对象window上的方法，内部函数this指向window
setInterval(function () {},100)
clearInterval()

// 推迟指定的时间执行一次
setTimeout(function () {}, 100)
clearTimeout();






// 查看滚动条的滚动距离(IE8及IE8以下不兼容)
window.pageXOffset //查看滚动条X轴的滚动距离
window.pageYOffset //查看滚动条Y轴的滚动距离


// 查看滚动条滚动的距离(IE8和IE8以下的浏览器兼容下面的方法)
// 这两种方法里面有个规矩，只要在某个浏览器中其中一个方法能获取值，另外一个的值肯定是零
// 最好的方法就是下面这两个方法的值相加
document.documentElement.scrollLeft //查看滚动条X轴的滚动距离
document.documentElement.scrollTop //查看滚动条Y轴的滚动距离
document.body.scrollTop   //查看滚动条Y轴的滚动距离
document.body.scrollLeft  //查看滚动条X轴的滚动距离



// 封装一个getScrollOffset方法求滚动条的距离
function getScrollOffset() {
    if(window.pageYOffset) {
        return {
            x : window.pageXOffset,
            y : window.pageYOffset,
        }
    }else{
        return {
            y : document.body.scrollTop + document.documentElement.scrollTop,
            x : document.body.scrollLeft + document.documentElement.scrollLeft,
        }
    }
}





// 查看可视区窗口尺寸
// IE8及IE8以下不兼容
window.innerWidth  //查看可视区窗口的宽度
window.innerHeight //查看可视区窗口的高度

// 标准模式下，任意浏览器都兼容
document.documentElement.clientHeight //查看可视区窗口的高度
document.documentElement.clientWidth //查看可视区窗口的宽度

// 适用于怪异模式下的浏览器
document.body.clientWidth  //查看可视区窗口的宽度
document.body.clientHeight //查看可视区窗口的高度

// 判断是标准模式还是怪异模式
// html页面的页面中第一行如果有<!DOCTYPE html>则是标准模式
// 如果我注释<!DOCTYPE html>则设置为怪异模式
// 判断标准模式还是怪异模式的方法
document.compatMode  //如果返回的结果是"CSS1Compat"则是标准模式
document.compatMode  //如果返回的结构是"BackCompat"则是怪异模式


// 封装兼容性方法，返回浏览器可视区窗口的尺寸getViewportOffset()方法
function getViewportOffset() {
    if(window.innerHeight) {
        return {
            width : window.innerWidth,
            height : window.innerHeight,
        }
    }else{
        if(document.compatMode == "BackCompat") {
            return {
                width : document.body.clientWidth,
                height : document.body.clientHeight,
            }
        }else {
            return {
                width : document.documentElement.clientHeight,
                height : document.documentElement.clientWidth,
            }
        }
    }
}






// 查看一个元素的几何尺寸(包含了该元素的几乎一切信息)
// 查看一个元素的几何尺寸(包含 )
// 兼容性很好
div.getBoundingClientRect()  //基本不用下面的方法可以替代它
// 该方法返回一个对象，对象里面有left,top,right,bottom等属性。
// left和top代表该元素左上角的X和Y坐标，right和bottom代表元素右下角的X和Y坐标。
// height和width属性老版本IE并未实现
// 返回的结构并不是实时的


// 查看一个元素的尺寸
div.offsetWidth   //求元素的宽(求的是视觉上的尺寸)
div.offsetHeight  //求元素的高(求的是视觉上的尺寸)

// 查看一个元素的位置
// 对于无定位的元素，返回相对于文档的坐标。
// 对于有定位的腹肌，返回当前相对于最近的有定位的父级坐标。
div.offsetTop   //求元素离顶端的距离
div.offsetLeft  //求元素离左侧的距离


// 返回最近有定位的父级，如果没有，则返回body
div.offsetParent


// 封装一个方法求一个元素离文档的left和top的距离
function getElementPostioin(target) {
    var left = 0;
    var top = 0;
    function getElementleft(target) {
        left += target.offsetLeft
        top  += target.offsetTop
        if(target == document.body) {
            return
        }
        target = target.offsetParent
        getElementleft(target);
    }
    getElementleft(div1);
    return {
        left : left,
        top : top,
    }
}






// 让滚动条滚动
// window上有三个方法
// 三个方法功能类似，用法将x，y轴坐标传入。即实现让滚动条当前位置。
// 区别scrollBy()会在之前的数据基础上做累加。
window.scroll(x, y);      //滚动条需要滚动到哪个位置   
window.scrollTo(x, y);    //滚动条需要滚到到哪个位置
window.scrollBy(x, y);    //执行一次滚动条滚动的距离


// 利用scrollBy()实现快速阅读的功能
var div1 = document.getElementsByTagName('div')[0];
var div2 = document.getElementsByTagName('div')[1];
var div3 = document.getElementsByTagName('div')[2];
var cleanTime;
var key = true;
div1.onclick = function() {
    if(key) {
        cleanTime = setInterval(function() {
            window.scrollBy(0, 2);
        }, 100)
        key = false;
    }
}
div2.onclick = function() {
    clearInterval(cleanTime);
    key = true;
}
div3.onclick = function() {
    window.scrollTo(0, 0);
}





// 脚本化css
// 可读写行间样式，没有兼容性问题，碰到float这样的保留字属性，前面应该加上css
// float ---> cssFloat
// 例如行间有一个float：left；  div.style.cssFloat
// 符合属性必须拆解，组合单词编程小驼峰式写法
// 写入的值必须是字符串格式
div.style.width = '100px';   //设置div的宽度为100px
div.style.width //获取div的宽度值








// 获取元素显示样式(css文件里面的也可以识别)
// 计算样式只读
// 返回的计算样式的值都是绝对值，没有相对单位
// IE8及IE8以下不兼容
window.getComputedStyle(div, null)   //返回元素样式对象
window.getComputedStyle(div, null).width   //返回元素样式对象中的width值


// 使用window.getComputedStyle() 获取伪元素的样式
window.getComputedStyle(div, 填伪元素)
window.getComputedStyle(div, 'after').height

// IE8及IE8以下里面的查询样式
// 计算样式只读
// 返回的计算样式的值不是经过转换的绝对值
// IE独有属性
div.currentStyle
div.currentStyle.width


// 改变伪元素的属性
// 无法从js方面下手,只能从css中下手
// 可以用setAttribute来改变元素的属性从而间接操作伪元素






// 方块加速运动的小案例
var div = document.getElementsByTagName('div')[0];
var speed = 1;
var clean = setInterval(function() {
    speed += speed / 7
    div.style.top = parseInt(window.getComputedStyle(div, null).top) + speed  + 'px'
    if(parseInt(div.style.top) > 600) {
        clearInterval(clean);
    }
}, 10)



// 减速运动
var div = document.getElementsByTagName('div')[0];
var speed = 20;
var clean = setInterval(function() {
    speed -= speed / 30
    if(speed <= 1) {
        clearInterval(clean)
    }
    div.style.top = parseInt(window.getComputedStyle(div, null).top) + speed  + 'px'
    if(parseInt(div.style.top) > 500) {
        clearInterval(clean);
        div.style.top = '500px'
    }
    console.log(speed)
}, 10)






// 事件
// 点击事件
// 第一种绑定方式(this指向自己)
// 兼容性很好，但是一个元素上的同一个时间上只能绑定一个
// 基本等同于写在HTML行间上
div.onclick = function() {
    console.log('点击事件')
}
// 取消事件绑定的方法 在某种条件下让事件方法等于null
var count = 0;
div.onclick = function() {
    count ++;
    if(count == 5) {
        div.onclick = null;   //让它等于null
    }
    console.log(count)
}





// 第二种绑定方式(this指向自己)
// IE9以下不兼容，可以为一个时间绑定多个程序
div.addEventListener('填事件类型', 事件处理函数, false);
// 例如
function test() {
    console.log('test');
}
div.addEventListener('click', test, false)
// 例如
div.addEventListener('click', function() {
    console.log('test');
}, false)

// 取消事件绑定的方法(需要吧方法写到外面才能解除事件绑定)
// 注意：若绑定函数匿名，则无法解除
function test() {
    console.log('test')
    this.removeEventListener('click', test, false)
}
li[0].addEventListener('click', test, false)





// 第三种绑定方式(this指向window)
// IE独有，一个事件可以绑定多个程序
div.attachEvent('on' + 事件类型, 事件处理函数)




// 封装兼容性的addEvent(elem, type, handle); 方法(解决绑定事件的兼容性问题)
function addEvent(elem, type, handle) {
    if(elem.addEventListener) {
        elem.addEventListener(type, handle, false)
    }else if(elem.attachEvent){
        elem.attachEvent('on' + type, function() {
            handle.call(elem);
        })
    }else{
        elem['on' + type] = handle;
    }
}
addEvent(div, 'click', function() {
    console.log('test')
})












// 事件处理模型---事件冒泡、捕获
// 事件冒泡:
    // 结构上(非视觉上)嵌套关系的元素，会存在事件冒泡的功能
    // 即同一事件，自子元素冒泡向父元素。(自底向上)


// 事件捕获：
    // 结构上(非视觉上)嵌套关系的元素，会存在事件捕获的功能
    // 即同一事件，自父元素捕获至子元素(事件源元素)。(自顶向下)

    // IE没有捕获事件

// 触发顺序, 先捕获, 后冒泡
// focus, blur, change, submit, reset select 等事件不冒泡



// 事件冒泡
// HTML代码结构
/*
<div class="wrapper">
    <div class="content">
        <div class="box"></div>
    </div>
</div>
*/
var wrapper = document.getElementsByTagName('div')[0];
var content = wrapper.getElementsByTagName('div')[0];
var box = content.getElementsByTagName('div')[0];
wrapper.addEventListener('click', function() {
    console.log('wrapper')
}, false)
content.addEventListener('click', function() {
    console.log('content');
}, false)
box.addEventListener('click', function() {
    console.log('box')
}, false)
// 点击box,打印顺序是box--> content--> wrapper (自底向上)




// 事件捕获(触发方法,把addEventListener的最后一个参数改成true就可以触发事件捕获)
// HTML代码结构
/*
<div class="wrapper">
    <div class="content">
        <div class="box"></div>
    </div>
</div>
*/
var wrapper = document.getElementsByTagName('div')[0];
var content = wrapper.getElementsByTagName('div')[0];
var box = content.getElementsByTagName('div')[0];
wrapper.addEventListener('click', function() {
    console.log('wrapper')
}, true)
content.addEventListener('click', function() {
    console.log('content');
}, true)
box.addEventListener('click', function() {
    console.log('box')
}, true)

// 点击box,打印顺序是wrapper--> content--> box (自顶向下)












// 取消冒泡和阻止默认事件
// 取消冒泡：
    // W3C标准event.stopPropagation(); 但是不支持IE9以下版本
    // IE独有event.cancelBubble = true;
    // 封装取消冒泡的函数stopBubble(event);
function stopBubble(event) {
    if(event.stopPropagation) {
        event.stopPropagation()
    }else {
        event.cancelBubble = true
    }
}
    
// 阻止默认事件：
    // 默认事件一：表单提交,a标签跳转,右键菜单等
    // 1.return false；以对象属性的方式注册的事件才生效
    // 2.event.preventDefault(); W3C标准，IE9以下不兼容
    // 3.event.returnValue = false; 兼容IE
    // 封装阻止默认事件的函数cancelHandler(event);
function cancelHandler(event) {
    if(event.preventDefault) {
        event.preventDefault();
    }else {
        event.returnValue = false
    }
}
document.oncontextmenu = function(e) {
    cancelHandler(e);
}




// 例如取消a标签的默认事件
a.onclick = function(e) {
    e.preventDefault();
    console.log('取消a标签的默认事件')
}
// 也可以在行间写上JavaScript:void(false) 
// <a href="javascript:void(false)">www.baidu.com</a>




// 获取事件对象的兼容性写法
div.onclick = function(e) {
    // 谷歌浏览器用e  IE浏览器用window.event;
    var event = e || window.event;
}










// onclick      点击事件
// onmouseenter 鼠标移入
// onmouseleave 鼠标移出
// onmousemove  鼠标移动触发
// onmousedown  鼠标按下
// onmouseup    鼠标松开
// oncontextmenu 右键产生菜单事件



// onmousedown的button来区分左右键
// onmouseup的button来区分左右键
// 右键的button==2
// 滚轮的button==1
// 左键的button==0



// 判断鼠标的左右键和滚轮
document.oncontextmenu = function(e) {
    e.preventDefault();
}
document.onmousedown = function(e) {
    var event = e || window.event;
    console.log(event.button);
    if(event.button == 2) {
        console.log('右键')
    }else if(event.button==1){
        console.log('滚轮')
    }else{
        console.log('左键')
    }
}





// 判断是不是点击 用时间戳的方式来判断
var startTime = 0;
var endTime = 0;
var key = false;
document.onmousedown = function() {
    startTime = new Date().getTime();
}
document.onmouseup = function() {
    endTime = new Date().getTime();
    if(endTime - startTime < 300) {
        key = true;
    }else {
        key = false;
        console.log('拖拽')
    }
}
document.onclick = function() {
    if(key) {
        console.log('click')
    }
}







// 键盘事件
// keydown keyup keypress
// keydown > keypress > keyup   执行顺序
// keydown 和 keypress 的区别
// keydown可以响应任意键盘按键, keypress只可以响应字符类累按键(字符类按键就用keypress)
// keypress返回ASCII码，可以转换成相应字符
document.onkeydown = function(e) {
    var event = e || window.event;
    console.log(event);
}
document.onkeypress = function(e) {
    var event = e || window.event;
    console.log(event);
}







// 文本操作事件
// input focus blur change


// input事件(只要往input里面添加或者是删除操作就会触发该事件)
var input = document.getElementsByTagName('input')[0];
input.oninput = function() {
    console.log(this.value) 
}

// change 是指控件的值发生改变且失去焦点时触发的事件
var input = document.getElementsByTagName('input')[0];
input.onchange = function() {
    console.log(this.value)
}

// focus事件(鼠标聚焦触发该事件)
var input = document.getElementsByTagName('input')[0];
input.onfocus = function() {
    console.log(this.value)
}


// blur事件(失去焦点触发该事件)
var input = document.getElementsByTagName('input')[0];
input.onblur = function() {
    console.log(this.value)
}







// onload 等待页面所有加载完毕的时候才执行onload, 基本不使用，太慢了
window.onload = function() {
    console.log('test');
}


// 事件练习
// 随机移动方框
// 随机移动方块


// 练习
// 1.完善轮播图
// 2.提(qie)取密码框的密码
// 3.输入框功能完善
// 4.菜单栏
// 5.贪吃蛇游戏
// 6.扫雷游戏

